<?php

namespace app\common\logic;

use app\common\library\exception\ApiException;
use app\common\library\Helper\DateTime;
use app\common\library\TencentMap;
use app\common\model\Amap;
use app\common\model\Order;
use app\common\model\OrderComment;
use app\common\model\OrderCommentImage;
use app\common\model\OrderGoods;
use app\common\model\Shop;
use app\common\model\ShopGoods;
use app\common\model\ShopMember;
use app\common\model\Tag;
use Carbon\Carbon;
use function tests\thinkphp\library\think\func_trim;
use think\db\Query;
use app\common\library\Helper\Arr;
use think\Env;
use think\Log;
use think\response\Json;

class ShopNewLogic extends BaseLogic
{
    public $model;

    public function assignModel()
    {
        $this->model          = new Shop();
    }

    /**
     * 搜索条件处理
     * @param Query $query
     * @param array $params
     * @return Query
     */
    public function handleSearch(Query $query, array $params): Query
    {
        if (isset($params['city']) && !empty($params['city'])) {
            $query->where('s.city', $params['city']);
        }

        if (isset($params['is_cooperate']) && !empty($params['is_cooperate'])) {
            $query->where('s.is_cooperate', $params['is_cooperate']);
        }

        if (isset($params['status']) && !empty($params['status'])) {
            $query->where('s.status', $params['status']);
        }

        if (isset($params['audit_status']) && !empty($params['audit_status'])) {
            $query->where('s.audit_status', $params['audit_status']);
        }

        if (isset($params['is_del']) && !empty($params['is_del'])) {
            $query->where('s.is_del', $params['is_del']);
        }

        if (isset($params['districts']) && !empty($params['districts'])) {
            $query->where('s.districts', $params['districts']);
        }
        if (isset($params['keyword']) && !empty($params['keyword'])) {
            $tag_id = Tag::where('name','like','%'.$params['keyword'].'%')->value('id');
            $shop_ids = ShopGoods::alias('a')->join('fa_goods b','a.goods_id=b.id','left')->where(['b.goods_name'=>['like','%'.$params['keyword'].'%'],'a.status'=>1,'a.audit_status'=>1])->column('a.shop_id');
            if (!empty($tag_id)){
                $whereOrRaw = "s.shop_name  LIKE '%{$params['keyword']}%' or FIND_IN_SET({$tag_id},s.tags)";
            }else{
                $whereOrRaw = "s.shop_name  LIKE '%{$params['keyword']}%'";
            }
            if (!empty($shop_ids)){
                $ids = implode(',',$shop_ids);
                $whereOrRaw .= " or s.id in ({$ids})";
            }
            $query->where($whereOrRaw);
        }
        return $query;
    }

    /**
     * 商家分页列表
     * @param array $params
     * @return Json
     * @throws \think\exception\DbException
     */
    public function index(array $params)
    {
        if (!isset($params['cityId'])){
            //逆地址解析
            $result = reverseGeocoding($params['lat'],$params['lng']);
            $amaps = getAmaps();
            $city_info = getNameByChar($amaps,$result->city);
        }else{
            $city_info = Amap::field('id,name')->where('id',$params['cityId'])->find();

        }
        $params['status']      = 1;
        $params['audit_status']      = 1;
        $params['is_del']      = 0;
//        $params['city']      = $city_info['id'];
        $params['city']      = $city_info['id'];
        $params['orderBy']      = 'distance';
        $params['orderType']    = 'asc';
        $params['field']    = "s.id,s.logo,s.shop_name,s.phone,s.longitude,s.latitude,s.address,s.score,s.business_start_time,s.business_end_time,s.tags,(6378.138 * 2 * asin(sqrt(pow(sin((latitude * pi() / 180 - " . $params['lat'] . " * pi() / 180) / 2),2) + cos(latitude * pi() / 180) * cos(" . $params['lat'] . " * pi() / 180) * pow(sin((longitude * pi() / 180 - " . $params['lng'] . " * pi() / 180) / 2),2))) * 1000) as distance";
        $query = '';
        $subSql           = Order::where('order_status', '>', 0)->fieldRaw('count(id) as sale_num,shop_id')->group('shop_id')->buildSql();
        if (isset($params['sort']) && !empty($params['sort'])){
            if ($params['sort'] == 'distance'){ // 距离优先
                $params['orderBy']      = 'distance';
                $params['orderType']    = 'asc';
                $query = $this->model->alias('s')
                    ->join([$subSql => 'o'], 's.id = o.shop_id', 'LEFT');
            }elseif ($params['sort'] == 'sale'){ //销量排序
                $query = $this->model->alias('s')
                    ->join([$subSql => 'o'], 's.id = o.shop_id', 'LEFT');
                $params['orderBy']      = 'o.sale_num';
                $params['orderType']    = 'desc';
            }elseif ($params['sort'] == 'score'){ //评分排序
                $params['orderBy']      = 'score';
                $params['orderType']    = 'desc';
                $query = $this->model->alias('s')
                    ->join([$subSql => 'o'], 's.id = o.shop_id', 'LEFT')
                    ->order('s.' . $params['sort'] . ' desc');
            }
        }else{
            $query = $this->model->alias('s')
                ->join([$subSql => 'o'], 's.id = o.shop_id', 'LEFT');
        }
        if ($params['field'] ?? false) {
            $query->field($params['field']);
        }
        $query->with(['shopGoods' => function ($query) {
            $query->where(['status'=>1,'audit_status'=>1]);}]);
        if (isset($params['goods_id']) && !empty($params['goods_id'])) {
            $shopIds = ShopGoods::where(['goods_id'=>$params['goods_id'],'audit_status'=>1,'status'=>1])->group('shop_id')->column('shop_id');
            $query->where('s.id','in',$shopIds);
        }
        $query = $this->handleOrder($query,$params);
        $per_page = $params['per_page'] ?? 5;
        if (isset($params['type']) && $params['type'] == 'map') {//用于地图，需要全部获取，不能分页
            $per_page = 1000;
        }
        $list =  $this->handleSearch($query, $params)->paginate($per_page)->each(function (&$item) use ($params){
            $item['tags'] = Tag::where(['id'=>['in',$item['tags']]])->column('name');
            foreach ($item['shop_goods'] as &$value){
                $value['goods_name'] = $value['goods']['goods_name'];
                $value['sale_num'] = OrderGoods::getSaleNumByShopGoodsId($item['id'], $value['goods_id']);
                $price_info = ShopGoods::getPrice($value['market_price']);//价格
                $value['price'] = $price_info['price'];
                $value['price_tip'] =$price_info['price_tip'];//价格提示
                unset($value['goods']);
            }
//            $item['distance'] = getDistance(['lat'=>$item['latitude'],'lng'=>$item['longitude'],'to'=>$params['lat'].','.$params['lng']]);//获取距离
            $item['distance'] = '距离'.round($item['distance']/1000,2).'km';
            $item['phone_arr'] = explode(',',$item['phone']);
            return $item;
        })->toArray();
        $list['city_info'] = $city_info;
        return $list;
    }

    /**
     * 商家详情
     * @param array $params
     * @return mixed
     * @throws \think\Exception
     */
    public function info(array $params)
    {
        $shop = $this->model->with(['shopGoods' => function ($query) {
            $query->field('id,goods_id,shop_id,price,market_price')->where(['status'=>1,'audit_status'=>1])->with(['goods']);
        },'shopImages','comment'=>function($query){$query->order('id desc')->with('member')->limit(2);}])->field("id,logo,shop_name,phone,longitude,latitude,address,score,business_start_time,detail,attention,business_end_time,tags")->find($params['shop_id']);
        if (!$shop)
            throw new ApiException('店铺信息不存在');
        $shop['tags'] = Tag::where(['id'=>['in',$shop['tags']]])->column('name');
        if (isset($params['lat']) && !empty($params['lat'])){
//            $shop['distance'] = getDistance(['lat'=>$shop['latitude'],'lng'=>$shop['longitude'],'to'=>$params['lat'].','.$params['lng']]);//获取距离
            $shop['distance'] = getStraightDistance($params['lat'],$params['lng'],$shop['latitude'],$shop['longitude']);//获取距离
            $shop['distance'] = '距离'. $shop['distance'].'km';
        }else{
            $shop['distance'] = '';
        }
        $shop['phone_arr'] = explode(',',$shop['phone']);
        foreach ($shop['shop_goods'] as &$value){
            $value['goods_name'] = $value['goods']['goods_name'];
            $value['sale_num'] = OrderGoods::getSaleNumByShopGoodsId($shop['id'], $value['goods_id']);
            $price_info = ShopGoods::getPrice($value['market_price']);//价格
            $value['price'] = $price_info['price'];
            $value['price_tip'] =$price_info['price_tip'];//价格提示
            unset($value['goods']);
        }
        $shop['recharge_info'] = ['image'=>Env::get('app.app_host').'/uploads/recharge/1.png','url'=>'/pages/client/balance/invest'];
        $shop['images'] = !empty($shop['shop_images']) ? array_column($shop['shop_images']->toArray(), 'image_url') : [];
        //商品评价
        if (!empty($shop['comment'])){
            $arr['list'] = $shop['comment'];
            $arr['praise_rate'] = '';
            unset($shop['comment']);
            foreach ($arr['list']  as &$value){
                //获取图片
//                OrderCommentImage::where('order_comment_id',$value['id'])->select()
                //评论名称获取
                $value['member_name'] = getCommentName($value['member']['member_name'],$value['anonymous']);
                $value['service_name'] = OrderGoods::where(['order_id'=>$value['order_id']])->value('goods_name');
                unset($value['order_id'],$value['shop_id'],$value['updatetime'],$value['deletetime'],$value['shop_goods_id'],$value['member_id'],$value['member']);
            }
            if (!empty($arr['list'])){
                //获取好评数
                $good_num = OrderComment::where(['shop_id'=>$shop['id'],'star'=>['gt',3]])->count('id');
                //获取总评论数
                $all_num = OrderComment::where(['shop_id'=>$shop['id']])->count('id');
                $arr['praise_rate'] = '0%';
                if ($all_num != 0){
                    $arr['praise_rate'] = (sprintf("%01.2f", $good_num / $all_num) * 100).'%';
                }
                $arr['all_num'] = $all_num;
            }
            $shop['comment'] = $arr;
//            unset($info['comment']);
        }
        unset($shop['shop_images']);
        return $shop;
    }



    /**
     * 距离计算
     * @param $data
     * @param $params
     * @return array
     */
    public function handleDistance($data, $params): array
    {
        $toArr = [];
        foreach ($data as $datum) {
            $toArr[] = $datum['latitude'] . ',' . $datum['longitude'];
        }
        $toStr  = implode(';', $toArr);
        $req    = [
            'from' => $params['lat'] . ',' . $params['lng'],
            'to'   => $toStr
        ];
        $mapRes = TencentMap::instance()->matrix($req);
        if (isset($mapRes['rows'])) {
            foreach ($mapRes['rows'][0]['elements'] as $k => $ele) {
                $data[$k]['distance'] = number_format($ele['distance'] / 1000, 2, '.', '');
            }
        }
        return $data;
    }

    /**
     * 商家端-商家信息
     * @return mixed
     */
    public function shopInfo()
    {
        $shop = $this->model->find($this->shopId);
        return $this->resourceHandle->shopInfo($shop);
    }

    /**
     * 商家端-更新营业时间
     * @param array $params
     * @return mixed
     * @throws ApiException
     */
    public function editBusinessTime(array $params = [])
    {
        if(Carbon::parse($params['business_start_time'])->gte(Carbon::parse($params['business_end_time']))) {
            throw new ApiException('营业开始时间不能大于等于结束时间',404);
        }
        $shop                      = $this->model->find($this->shopId);
        $shop->business_start_time = $params['business_start_time'] ?? '09:00';
        $shop->business_end_time   = $params['business_end_time'] ?? '21:00';
        return $shop->save();
    }

    /**
     * 商家标签列表
     * @return bool|\PDOStatement|string|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function tagList()
    {
        $shop = $this->model->find($this->shopId);
        $shopTags = explode(',',$shop->tags) ?? [];
        $tags = model('tag')->where('status', $this->enable)->order('sort desc')->select();
        foreach ($tags as $tag) {
            $tag->is_checked = 0;
            if (in_array($tag->id, $shopTags)) {
                $tag->is_checked = 1;
            }
            unset($tag['sort'],$tag['status'],$tag['createtime'],$tag['updatetime'],$tag['deletetime']);
        }
        return $tags;
    }

    /**
     * 保存商家标签
     * @param $params
     * @return false|\think\Model
     */
    public function saveTags($params)
    {
        // 过滤不存在标签
        $tagIds = model('tag')->where('status', $this->enable)->column('id');
        $tags = array_intersect($params['tags'], $tagIds);
        $this->getModel()->where('id', $this->shopId)->update(['tags' => implode(',',$tags)]);
        return true;
    }
}